package com.zyk.scaffold.tcp.utils;

import cn.hutool.core.codec.Base64;
import com.zyk.scaffold.common.utils.AssertUtil;
import com.zyk.scaffold.common.utils.MD5Util;
import com.zyk.scaffold.tcp.constant.TcpConstants;
import com.zyk.scaffold.tcp.holder.PropertiesHolder;
import com.zyk.scaffold.tcp.proto3.MessageBuf;
import lombok.extern.slf4j.Slf4j;

import java.security.NoSuchAlgorithmException;
import java.util.function.Function;


@Slf4j
public class MsgUtils {
    public static MessageBuf.JMTransfer buildReplyOK(){
        return build(null, jm -> jm.setMsgType(MessageBuf.JMTransfer.MsgType.REPLY)
                        .setBody(MessageBuf.JMTransfer.Body.newBuilder()
                                .setMsg("OK")
                                .build()
                        )
                , Boolean.FALSE);
    }

    public static MessageBuf.JMTransfer buildReplyToken(MessageBuf.JMTransfer message, String token) throws Exception {
        return build(
                message,
                jm -> jm.setMsgType(MessageBuf.JMTransfer.MsgType.PUSH)
                .setBody(MessageBuf.JMTransfer.Body.newBuilder()
                        .setMsg(token)
                        .build()),
                Boolean.TRUE
        );
    }

    public static MessageBuf.JMTransfer buildError(String error) {
        return build(null, jm -> jm.setMsgType(MessageBuf.JMTransfer.MsgType.ERROR)
                .setBody(MessageBuf.JMTransfer.Body.newBuilder()
                        .setMsg(error)
                        .build()
                )
                , Boolean.FALSE);
    }

    public static MessageBuf.JMTransfer build(Function<MessageBuf.JMTransfer.Builder, MessageBuf.JMTransfer.Builder> callBack) throws Exception{
        return build(null, callBack, Boolean.TRUE);
    }

    public static MessageBuf.JMTransfer build(MessageBuf.JMTransfer target, Function<MessageBuf.JMTransfer.Builder, MessageBuf.JMTransfer.Builder> callBack, Boolean throwEx) {
        MessageBuf.JMTransfer.Builder builder;
        if(target == null){
            builder = MessageBuf
                    .JMTransfer
                    .newBuilder();
        }else{
            builder = MessageBuf.JMTransfer.newBuilder(target);
        }
        return sign(callBack.apply(
                builder
                        .setTimeStamp(System.currentTimeMillis() + "")
                        .setEncryptionType(MessageBuf.JMTransfer.EncryptionType.NONE)
        ), throwEx).build();
    }

    private static MessageBuf.JMTransfer.Builder sign(MessageBuf.JMTransfer.Builder builder, Boolean throwEx) {
        String msg = builder.getBody().getMsg();
        String timeStamp = builder.getTimeStamp();
        String target = Base64.encode(msg) + timeStamp + PropertiesHolder.getEnvironment().getProperty(TcpConstants.TCP_SERVER_PROPERTIES_KEY_APP_SECRET, "null");
        MessageBuf.JMTransfer.Builder builderTmp = builder;
        try {
            builderTmp = builder.setSign(MD5Util.computeMD5(target));
        } catch (NoSuchAlgorithmException e) {
            log.error("签名异常", e);
            if(throwEx){
                AssertUtil.error("签名异常", e);
            }
            builderTmp = builderTmp.setMsgType(MessageBuf.JMTransfer.MsgType.ERROR)
                    .setBody(MessageBuf.JMTransfer.Body.newBuilder()
                            .setMsg("签名异常")
                            .build()
                    );
        }
        return builderTmp;
    }
}
